#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AI评估模块 - 基于DeepSeek API的薪资信息评估
"""

import requests
import json
import time
from typing import Dict, List, Tuple, Optional
from datetime import datetime
import logging
import sys

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class DeepSeekEvaluator:
    """DeepSeek API评估器"""
    
    def __init__(self, api_key: str):
        """
        初始化评估器
        
        Args:
            api_key: DeepSeek API密钥
        """
        self.api_key = api_key
        self.base_url = "https://api.deepseek.com/v1/chat/completions"
        self.headers = {
            "Authorization": "Bearer " + api_key,
            "Content-Type": "application/json"
        }
        
        # 薪资评估提示词模板
        self.salary_evaluation_prompt = """
你是一个专业的客服聊天记录分析专家。请分析以下聊天消息是否包含薪资相关信息。

薪资相关信息包括但不限于：
- 工资、薪资、薪水、待遇、收入、报酬
- 具体的金额数字（如：133元、299元、6000元、8000元、20000元等）
- 日结、月结、保底、提成等薪资相关词汇
- 工作时间和收入的对应关系
- 收入承诺或保证

请对每条消息进行评分：
- 评分范围：0-100分
- 0-30分：不包含薪资信息
- 31-70分：可能包含薪资信息，需要进一步确认
- 71-100分：明确包含薪资信息

请按照以下JSON格式返回结果：
{{
    "score": 评分(0-100),
    "is_salary_related": true/false,
    "reason": "详细的判断依据和理由",
    "detected_keywords": ["检测到的关键词列表"]
}}

聊天消息内容：
{message_content}
"""

        # 要照片评估提示词模板
        self.photo_request_evaluation_prompt = """
你是一个专业的客服聊天记录分析专家。请分析以下聊天消息是否包含索要照片的相关信息。

索要照片相关信息包括但不限于：
- 直接要求发照片：发照片、发个照片、发张照片等
- 要求发生活照：发生活照、发个生活照等
- 要求发自拍：发自拍、发个自拍等
- 间接索要照片：看看照片、发张看看、评估、上镜、整体感觉等
- 暗示性要求：需要照片、要你的照片等

请对每条消息进行评分：
- 评分范围：0-100分
- 0-30分：不包含要照片信息
- 31-70分：可能包含要照片信息，需要进一步确认
- 71-100分：明确包含要照片信息

请按照以下JSON格式返回结果：
{{
    "score": 评分(0-100),
    "is_photo_request": true/false,
    "reason": "详细的判断依据和理由",
    "detected_keywords": ["检测到的关键词列表"]
}}

聊天消息内容：
{message_content}
"""

        # 同时评估两种信息的提示词模板
        self.multi_criteria_evaluation_prompt = """
你是一个专业的客服聊天记录分析专家。请同时分析以下聊天消息是否包含薪资信息和要照片信息。

薪资相关信息包括但不限于：
- 工资、薪资、薪水、待遇、收入、报酬
- 具体的金额数字（如：133元、299元、6000元、8000元、20000元等）
- 日结、月结、保底、提成等薪资相关词汇

索要照片相关信息包括但不限于：
- 直接要求发照片：发照片、发个照片、发张照片等
- 要求发生活照：发生活照、发个生活照等
- 要求发自拍：发自拍、发个自拍等
- 间接索要照片：看看照片、发张看看、评估、上镜、整体感觉等

请对每条消息进行评分：
- 薪资相关评分范围：0-100分
- 要照片相关评分范围：0-100分
- 0-30分：不包含相关信息
- 31-70分：可能包含相关信息，需要进一步确认
- 71-100分：明确包含相关信息

请按照以下JSON格式返回结果：
{{
    "salary_score": 薪资评分(0-100),
    "is_salary_related": true/false,
    "salary_reason": "薪资相关的判断依据和理由",
    "photo_score": 要照片评分(0-100),
    "is_photo_request": true/false,
    "photo_reason": "要照片的判断依据和理由",
    "detected_keywords": ["检测到的关键词列表"]
}}

聊天消息内容：
{message_content}
"""

    def evaluate_salary_info(self, message_content: str) -> Dict:
        """
        评估单条消息是否包含薪资信息
        
        Args:
            message_content: 消息内容
            
        Returns:
            评估结果字典
        """
        logger.info(f"[AI评估] 开始评估消息，长度: {len(message_content)}")
        logger.debug(f"[AI评估] 消息内容: {message_content[:100]}...")
        try:
            # 构建请求数据
            prompt = self.salary_evaluation_prompt.format(message_content=message_content)
            
            data = {
                "model": "deepseek-chat",
                "messages": [
                    {
                        "role": "user",
                        "content": prompt
                    }
                ],
                "temperature": 0.1,
                "max_tokens": 500
            }
            
            # 发送请求
            logger.debug(f"[AI评估] 发送请求到API: {self.base_url}")
            response = requests.post(
                self.base_url,
                headers=self.headers,
                json=data,
                timeout=30
            )
            
            logger.debug(f"[AI评估] API响应状态码: {response.status_code}")
            if response.status_code == 200:
                result = response.json()
                content = result['choices'][0]['message']['content']
                
                # 清理响应内容
                clean_content = content.strip()
                if clean_content.startswith('```json'):
                    clean_content = clean_content[7:]
                if clean_content.endswith('```'):
                    clean_content = clean_content[:-3]
                clean_content = clean_content.strip()
                
                # 解析JSON
                logger.debug(f"[AI评估] API返回内容: {clean_content[:200]}...")
                try:
                    evaluation_result = json.loads(clean_content)
                    logger.info(f"[AI评估] 评估成功 - 分数: {evaluation_result.get('score', 0)}, 薪资相关: {evaluation_result.get('is_salary_related', False)}")
                    return {
                        'success': True,
                        'score': evaluation_result.get('score', 0),
                        'is_salary_related': evaluation_result.get('is_salary_related', False),
                        'reason': evaluation_result.get('reason', ''),
                        'detected_keywords': evaluation_result.get('detected_keywords', []),
                        'raw_response': content
                    }
                except json.JSONDecodeError as e:
                    logger.warning(f"[AI评估] JSON解析失败: {str(e)}")
                    logger.warning(f"[AI评估] 原始内容: {repr(clean_content)[:500]}")
                    # 尝试修复JSON格式
                    fixed_content = self._fix_json_format(clean_content)
                    if fixed_content:
                        try:
                            evaluation_result = json.loads(fixed_content)
                            return {
                                'success': True,
                                'score': evaluation_result.get('score', 0),
                                'is_salary_related': evaluation_result.get('is_salary_related', False),
                                'reason': evaluation_result.get('reason', ''),
                                'detected_keywords': evaluation_result.get('detected_keywords', []),
                                'raw_response': content
                            }
                        except json.JSONDecodeError:
                            pass
                    # 如果修复失败，使用文本解析
                    return self._parse_text_response(content)
                
        except json.JSONDecodeError as e:
            logger.warning("JSON解析失败，使用文本解析: " + str(e))
            try:
                return self._parse_text_response(content)
            except Exception as parse_error:
                logger.error("文本解析也失败: " + str(parse_error))
                pass
        except requests.exceptions.Timeout:
            logger.error("[AI评估] API请求超时")
        except Exception as e:
            logger.error(f"[AI评估] 评估过程中发生错误: {str(e)}", exc_info=True)
        
        # 默认返回
        logger.warning("[AI评估] 评估失败，返回默认结果")
        return {
            'success': False,
            'error': '评估失败',
            'score': 0,
            'is_salary_related': False,
            'reason': '评估失败',
            'detected_keywords': []
        }
    
    def _fix_json_format(self, content: str) -> str:
        """
        尝试修复JSON格式问题
        
        Args:
            content: 原始内容
            
        Returns:
            修复后的内容，如果无法修复则返回None
        """
        import re
        
        # 移除多余的换行符和空格
        fixed = content.replace('\n', ' ').replace('\r', ' ')
        fixed = re.sub(r'\s+', ' ', fixed).strip()
        
        # 如果内容被截断，尝试补全
        if fixed.startswith('{') and not fixed.endswith('}'):
            # 尝试找到最后一个完整的字段
            if '"score"' in fixed and not fixed.endswith('"'):
                # 补全score字段
                if '"score":' in fixed and not re.search(r'"score":\s*\d+', fixed):
                    fixed = re.sub(r'"score":\s*$', '"score": 0', fixed)
                if not fixed.endswith('}'):
                    fixed += '}'
        
        # 尝试提取完整的JSON对象
        json_match = re.search(r'\{.*\}', fixed)
        if json_match:
            return json_match.group(0)
        
        return None
    
    def _parse_text_response(self, content: str) -> Dict:
        """
        解析文本响应（当JSON解析失败时使用）
        
        Args:
            content: API返回的文本内容
            
        Returns:
            解析后的结果字典
        """
        import re
        
        # 智能文本解析逻辑
        score = 0
        is_salary_related = False
        reason = content
        detected_keywords = []
        
        # 尝试多种方式提取分数
        score_patterns = [
            r'(\d+)分',
            r'score[:\s]*(\d+)',
            r'评分[:\s]*(\d+)',
            r'(\d+)\s*分',
            r'"score":\s*(\d+)',
            r'score.*?(\d+)'
        ]
        
        for pattern in score_patterns:
            score_match = re.search(pattern, content, re.IGNORECASE)
            if score_match:
                try:
                    score = int(score_match.group(1))
                    break
                except ValueError:
                    continue
        
        # 尝试从文本中判断是否包含薪资信息
        salary_indicators = [
            r'包含.*薪资',
            r'薪资.*相关',
            r'工资.*信息',
            r'明确.*薪资',
            r'is_salary_related.*true',
            r'薪资.*信息',
            r'"is_salary_related":\s*true',
            r'is_salary_related.*True'
        ]
        
        for indicator in salary_indicators:
            if re.search(indicator, content, re.IGNORECASE):
                is_salary_related = True
                break
        
        # 如果分数很高，也认为是薪资相关
        if score >= 70:
            is_salary_related = True
        
        # 从原始消息内容中提取关键词（如果提供了原始消息）
        if 'raw_response' in locals() and raw_response:
            keyword_patterns = [
                r'工资|薪资|薪水|待遇|收入|报酬',
                r'\d+元|\d+块钱|\d+k|\d+K',
                r'日结|月结|保底|提成'
            ]
            
            for pattern in keyword_patterns:
                matches = re.findall(pattern, raw_response)
                detected_keywords.extend(matches)
        
        return {
            'success': True,
            'score': score,
            'is_salary_related': is_salary_related,
            'reason': reason,
            'detected_keywords': list(set(detected_keywords)),
            'raw_response': content
        }
    
    def batch_evaluate_messages(self, messages: List[Dict]) -> List[Dict]:
        """
        批量评估多条消息
        
        Args:
            messages: 消息列表，每个消息包含content字段
            
        Returns:
            评估结果列表
        """
        results = []
        
        for i, message in enumerate(messages):
            logger.info("正在评估第 " + str(i+1) + "/" + str(len(messages)) + " 条消息")
            
            result = self.evaluate_salary_info(message.get('content', ''))
            result['message_index'] = i
            result['message_id'] = message.get('id', i)
            result['candidate_id'] = message.get('candidate_id', '')
            result['sender'] = message.get('sender', '')
            result['created_at'] = message.get('created_at', '')
            
            results.append(result)
            
            # 添加延迟避免API限制
            time.sleep(0.5)
        
        return results
    
    def evaluate_photo_request_info(self, message_content: str) -> Dict:
        """
        评估单条消息是否包含要照片信息
        
        Args:
            message_content: 消息内容
            
        Returns:
            评估结果字典
        """
        logger.info(f"[AI评估] 开始评估消息要照片信息，长度: {len(message_content)}")
        logger.debug(f"[AI评估] 消息内容: {message_content[:100]}...")
        try:
            # 构建请求数据
            prompt = self.photo_request_evaluation_prompt.format(message_content=message_content)
            
            data = {
                "model": "deepseek-chat",
                "messages": [
                    {
                        "role": "user",
                        "content": prompt
                    }
                ],
                "temperature": 0.1,
                "max_tokens": 500
            }
            
            # 发送请求
            logger.debug(f"[AI评估] 发送请求到API: {self.base_url}")
            response = requests.post(
                self.base_url,
                headers=self.headers,
                json=data,
                timeout=30
            )
            
            logger.debug(f"[AI评估] API响应状态码: {response.status_code}")
            if response.status_code == 200:
                result = response.json()
                content = result['choices'][0]['message']['content']
                
                # 清理响应内容
                clean_content = content.strip()
                if clean_content.startswith('```json'):
                    clean_content = clean_content[7:]
                if clean_content.endswith('```'):
                    clean_content = clean_content[:-3]
                clean_content = clean_content.strip()
                
                # 解析JSON
                logger.debug(f"[AI评估] API返回内容: {clean_content[:200]}...")
                try:
                    evaluation_result = json.loads(clean_content)
                    logger.info(f"[AI评估] 评估成功 - 分数: {evaluation_result.get('score', 0)}, 要照片相关: {evaluation_result.get('is_photo_request', False)}")
                    return {
                        'success': True,
                        'score': evaluation_result.get('score', 0),
                        'is_photo_request': evaluation_result.get('is_photo_request', False),
                        'reason': evaluation_result.get('reason', ''),
                        'detected_keywords': evaluation_result.get('detected_keywords', []),
                        'raw_response': content
                    }
                except json.JSONDecodeError as e:
                    logger.warning(f"[AI评估] JSON解析失败: {str(e)}")
                    # 返回默认结果
                    return {
                        'success': False,
                        'error': 'JSON解析失败',
                        'score': 0,
                        'is_photo_request': False,
                        'reason': '评估失败',
                        'detected_keywords': []
                    }
                
        except requests.exceptions.Timeout:
            logger.error("[AI评估] API请求超时")
        except Exception as e:
            logger.error(f"[AI评估] 评估过程中发生错误: {str(e)}", exc_info=True)
        
        # 默认返回
        logger.warning("[AI评估] 评估失败，返回默认结果")
        return {
            'success': False,
            'error': '评估失败',
            'score': 0,
            'is_photo_request': False,
            'reason': '评估失败',
            'detected_keywords': []
        }
    
    def evaluate_multi_criteria(self, message_content: str) -> Dict:
        """
        同时评估消息的薪资和要照片两种信息
        
        Args:
            message_content: 消息内容
            
        Returns:
            评估结果字典，包含薪资和要照片两种评估结果
        """
        logger.info(f"[AI评估] 开始多维度评估消息，长度: {len(message_content)}")
        logger.debug(f"[AI评估] 消息内容: {message_content[:100]}...")
        try:
            # 构建请求数据
            prompt = self.multi_criteria_evaluation_prompt.format(message_content=message_content)
            
            data = {
                "model": "deepseek-chat",
                "messages": [
                    {
                        "role": "user",
                        "content": prompt
                    }
                ],
                "temperature": 0.1,
                "max_tokens": 800
            }
            
            # 发送请求
            logger.debug(f"[AI评估] 发送请求到API: {self.base_url}")
            response = requests.post(
                self.base_url,
                headers=self.headers,
                json=data,
                timeout=30
            )
            
            logger.debug(f"[AI评估] API响应状态码: {response.status_code}")
            if response.status_code == 200:
                result = response.json()
                content = result['choices'][0]['message']['content']
                
                # 清理响应内容
                clean_content = content.strip()
                if clean_content.startswith('```json'):
                    clean_content = clean_content[7:]
                if clean_content.endswith('```'):
                    clean_content = clean_content[:-3]
                clean_content = clean_content.strip()
                
                # 解析JSON
                logger.debug(f"[AI评估] API返回内容: {clean_content[:200]}...")
                try:
                    evaluation_result = json.loads(clean_content)
                    logger.info(f"[AI评估] 评估成功 - 薪资分数: {evaluation_result.get('salary_score', 0)}, 要照片分数: {evaluation_result.get('photo_score', 0)}")
                    
                    return {
                        'success': True,
                        'salary_score': evaluation_result.get('salary_score', 0),
                        'is_salary_related': evaluation_result.get('is_salary_related', False),
                        'salary_reason': evaluation_result.get('salary_reason', ''),
                        'photo_score': evaluation_result.get('photo_score', 0),
                        'is_photo_request': evaluation_result.get('is_photo_request', False),
                        'photo_reason': evaluation_result.get('photo_reason', ''),
                        'detected_keywords': evaluation_result.get('detected_keywords', []),
                        'raw_response': content
                    }
                except json.JSONDecodeError as e:
                    logger.warning(f"[AI评估] JSON解析失败: {str(e)}")
                    # 返回默认结果
                    return {
                        'success': False,
                        'error': 'JSON解析失败',
                        'salary_score': 0,
                        'is_salary_related': False,
                        'salary_reason': '评估失败',
                        'photo_score': 0,
                        'is_photo_request': False,
                        'photo_reason': '评估失败',
                        'detected_keywords': []
                    }
                
        except requests.exceptions.Timeout:
            logger.error("[AI评估] API请求超时")
        except Exception as e:
            logger.error(f"[AI评估] 评估过程中发生错误: {str(e)}", exc_info=True)
        
        # 默认返回
        logger.warning("[AI评估] 评估失败，返回默认结果")
        return {
            'success': False,
            'error': '评估失败',
            'salary_score': 0,
            'is_salary_related': False,
            'salary_reason': '评估失败',
            'photo_score': 0,
            'is_photo_request': False,
            'photo_reason': '评估失败',
            'detected_keywords': []
        }

    def evaluate_reply_reasonable(self, user_message: str, ai_reply: str) -> Dict:
        """
        评估AI回复是否合理
        
        Args:
            user_message: 用户消息
            ai_reply: AI回复
            
        Returns:
            评估结果字典
        """
        logger.info(f"[AI评估] 开始评估回复合理性 - 用户消息长度: {len(user_message)}, AI回复长度: {len(ai_reply)}")
        logger.debug(f"[AI评估] 用户消息: {user_message[:100]}...")
        logger.debug(f"[AI评估] AI回复: {ai_reply[:100]}...")
        
        try:
            prompt = f"""你是一个专业的AI智能客服对话质量评估专家，专门评估招聘直播主播岗位的客服回复质量。

## 背景信息
这是一个招聘直播主播岗位的客服系统（可能通过Boss直聘等平台招聘）。
- **工作性质**：视频露脸直播主播（纯聊天类型，不需要才艺）
- **平台**：B站（日结保底133元）或抖音（月结5000-8000元）
- **薪资模式**：日结保底 + 礼物提成（30%-51%）
- **工作地点**：居家线上直播，兼职全职都可以

## 关键评估标准（参考客服话术标准）

### 1. **信息准确性（权重：35%）**
**重点检查：**
- 薪资信息是否准确：
  - 日结保底133元（兼职4小时）或220元（全职6小时）
  - 日结发放规则：100元次日到账，33元次月25号发
  - 礼物提成：保底模式下30%，高提成模式40%-51%
  - 抖音月结：4小时5000元，6小时8000元
- 是否提供了具体数字（如"4小时日结133元"）而不是模糊描述
- 是否说明了具体发放时间（如"日结保底，没礼物也有保底发放"）
- 是否准确说明了提成比例和工作时间要求

### 2. **回复相关性（权重：25%）**
**重点检查：**
- 是否直接回答了用户的问题（如"日结多少钱"→"133元日结保底"）
- 对于用户询问的具体问题，是否提供了具体答案
- 是否理解用户意图（如用户问"保底吗"→应明确回答"是的，日结保底"）

### 3. **专业性（权重：20%）**
**重点检查：**
- 是否使用了专业的招聘术语
- 是否避免了过度口语化（如"宝子"、"哦"等）
- 是否表述清晰、逻辑完整
- 是否避免了欺骗性语言

### 4. **服务态度（权重：15%）**
**重点检查：**
- 语气是否友好、耐心
- 是否主动解答用户疑问
- 是否提供了详细的说明

### 5. **合法合规性（权重：5%）**
**重点检查：**
- 是否涉及不当要求（如索要隐私照片、要求付费、签约）
- 是否说明了正确的入职流程（提交照片初审→B站账号准备→录试镜视频）
- 是否避免了欺诈性承诺

## 常见问题评估标准

### 薪资询问
**用户问："日结保底多少" / "每天日结多少"**
- ✅ **合理回复**："4小时日结133元保底，每天先给你发100元，剩下33元保底次月25号统一给你发"
- ✅ **合理回复**："兼职4小时日结133元，全职6小时日结220元"
- ❌ **不合理回复**："日结保底200-500元"（不具体、可能夸大）
- ❌ **不合理回复**："加我微信详细说"（应该直接在对话中说明）
- ❌ **不合理回复**："保证月入过万"（虚假承诺）

### 保底询问
**用户问："没有礼物要求吧？"**
- ✅ **合理回复**："当天播满四个小时，不混播，认真对待直播，哪怕只有1块钱收入也有保底发放"
- ❌ **不合理回复**："没流量就没有保底"（日结保底永久有效）
- ❌ **不合理回复**："必须达到一定流水才有保底"

### 工作时间询问
**用户问："每天播几个小时"**
- ✅ **合理回复**："我们一周播五到六天，连播四个小时，保底133元"
- ✅ **合理回复**："兼职4小时，全职6小时"
- ❌ **不合理回复**："时间自己安排"（未说明具体时长要求）

### 平台选择询问
**用户问："抖音和B站有什么区别"**
- ✅ **合理回复**："抖音月结4小时5000元，B站日结133元，日结不需要流水要求"
- ✅ **合理回复**："抖音月结需要播满26天，B站日结对新人更友好"
- ❌ **不合理回复**："都差不多"（未说明具体区别）

## 用户消息
{user_message}

## AI回复
{ai_reply}

## 输出要求
请按照以下JSON格式返回评估结果：
{{
    "score": 评分(0-100),
    "is_reasonable": true/false,
    "reason": "详细的评估理由，重点说明在哪些维度上表现好或差",
    "strengths": ["具体的优点列表，如：'准确回答了用户关于薪资的询问'、'语气友好专业'"],
    "weaknesses": ["具体的缺点列表，如：'未提供具体的薪资构成说明'、'回复过于简单'"]
}}

## 评分细则
- **90-100分**：完美回复，所有维度都表现优秀，为用户提供极大帮助
- **80-89分**：优秀回复，主要维度表现良好，有轻微不足
- **70-79分**：合格回复，基本满足要求，但在某些维度有明显欠缺
- **60-69分**：勉强合格，回复有明显问题，但仍有一定价值
- **40-59分**：不合格回复，存在重要问题，如信息不准、态度不好等
- **0-39分**：严重不合格，误导用户、违反规范、态度恶劣等

请给出详细、专业的评估结果。
"""
            
            data = {
                "model": "deepseek-chat",
                "messages": [
                    {
                        "role": "user",
                        "content": prompt
                    }
                ],
                "temperature": 0.1,
                "max_tokens": 1000
            }
            
            # 发送请求
            logger.debug(f"[AI评估] 发送请求到API: {self.base_url}")
            response = requests.post(
                self.base_url,
                headers=self.headers,
                json=data,
                timeout=30
            )
            
            logger.debug(f"[AI评估] API响应状态码: {response.status_code}")
            if response.status_code == 200:
                result = response.json()
                content = result['choices'][0]['message']['content']
                
                # 清理响应内容
                clean_content = content.strip()
                if clean_content.startswith('```json'):
                    clean_content = clean_content[7:]
                if clean_content.endswith('```'):
                    clean_content = clean_content[:-3]
                clean_content = clean_content.strip()
                
                # 解析JSON
                logger.debug(f"[AI评估] API返回内容: {clean_content[:200]}...")
                try:
                    evaluation_result = json.loads(clean_content)
                    logger.info(f"[AI评估] 评估成功 - 分数: {evaluation_result.get('score', 0)}, 是否合理: {evaluation_result.get('is_reasonable', False)}")
                    
                    return {
                        'success': True,
                        'score': evaluation_result.get('score', 0),
                        'is_reasonable': evaluation_result.get('is_reasonable', False),
                        'reason': evaluation_result.get('reason', ''),
                        'strengths': evaluation_result.get('strengths', []),
                        'weaknesses': evaluation_result.get('weaknesses', []),
                        'raw_response': content
                    }
                except json.JSONDecodeError as e:
                    logger.warning(f"[AI评估] JSON解析失败: {str(e)}")
                    # 返回默认结果
                    return {
                        'success': False,
                        'error': 'JSON解析失败',
                        'score': 0,
                        'is_reasonable': False,
                        'reason': '评估失败',
                        'strengths': [],
                        'weaknesses': []
                    }
                
        except requests.exceptions.Timeout:
            logger.error("[AI评估] API请求超时")
        except Exception as e:
            logger.error(f"[AI评估] 评估过程中发生错误: {str(e)}", exc_info=True)
        
        # 默认返回
        logger.warning("[AI评估] 评估失败，返回默认结果")
        return {
            'success': False,
            'error': '评估失败',
            'score': 0,
            'is_reasonable': False,
            'reason': '评估失败',
            'strengths': [],
            'weaknesses': []
        }

    def evaluate_reply_reasonable_with_feedback(self, user_message: str, ai_reply: str, user_feedback: str, expected_label: str) -> Dict:
        """
        根据用户反馈调整提示词并重新评估AI回复是否合理
        
        Args:
            user_message: 用户消息
            ai_reply: AI回复
            user_feedback: 用户反馈和建议
            expected_label: 用户期望的标签（'合理' 或 '不合理'）
            
        Returns:
            评估结果字典
        """
        logger.info(f"[AI评估-反馈版] 开始根据用户反馈重新评估回复合理性")
        logger.info(f"[AI评估-反馈版] 用户消息长度: {len(user_message)}, AI回复长度: {len(ai_reply)}")
        logger.info(f"[AI评估-反馈版] 用户反馈: {user_feedback}")
        logger.info(f"[AI评估-反馈版] 期望标签: {expected_label}")
        logger.debug(f"[AI评估-反馈版] 用户消息: {user_message[:100]}...")
        logger.debug(f"[AI评估-反馈版] AI回复: {ai_reply[:100]}...")
        
        try:
            # 确保所有输入都是UTF-8编码的字符串
            user_message = str(user_message).encode('utf-8', errors='replace').decode('utf-8')
            ai_reply = str(ai_reply).encode('utf-8', errors='replace').decode('utf-8')
            user_feedback = str(user_feedback).encode('utf-8', errors='replace').decode('utf-8')
            expected_label = str(expected_label).encode('utf-8', errors='replace').decode('utf-8')
            
            logger.debug(f"[AI评估-反馈版] 编码检查完成")
            logger.debug(f"[AI评估-反馈版] 用户消息类型: {type(user_message)}")
            logger.debug(f"[AI评估-反馈版] AI回复类型: {type(ai_reply)}")
            logger.debug(f"[AI评估-反馈版] 用户反馈类型: {type(user_feedback)}")
            
            # 构建带用户反馈的提示词
            prompt = f"""你是一个智能客服对话质量评估专家。请根据用户的反馈和建议，重新评估以下对话对中AI的回复是否合理。

**用户反馈**：
{user_feedback}

**用户期望的标签**：{expected_label}

**原始对话内容**：
用户消息：{user_message}

AI回复：{ai_reply}

**请特别注意**：
1. 考虑用户的反馈，用户认为原始评估可能不准确
2. 结合用户的建议重新审视评估标准
3. 如果用户提供了更合理的判断依据，请优先考虑用户的观点
4. 确保评估结果更贴近用户期望的标签

请按照以下JSON格式返回结果：
{{
    "score": 评分(0-100),
    "is_reasonable": true/false,
    "reason": "详细的判断依据和理由（请说明是否采纳了用户反馈）",
    "strengths": ["回复的优点"],
    "weaknesses": ["回复的缺点或需要改进的地方"],
    "user_feedback_adopted": true/false,
    "feedback_explanation": "说明如何采纳了用户反馈"
}}

评分标准：
- 90-100分：非常合理，AI回复完美匹配用户需求
- 80-89分：合理，AI回复基本满足要求，有少量不足
- 70-79分：基本合理，AI回复大体合适但有明显缺陷
- 60-69分：勉强合理，AI回复有一定问题
- 0-59分：不合理，AI回复有明显错误或不合适
"""
            
            data = {
                "model": "deepseek-chat",
                "messages": [
                    {
                        "role": "user",
                        "content": prompt
                    }
                ],
                "temperature": 0.1,
                "max_tokens": 1500
            }
            
            # 发送请求
            logger.debug(f"[AI评估-反馈版] 发送请求到API: {self.base_url}")
            logger.debug(f"[AI评估-反馈版] 请求数据预览: {json.dumps(data, ensure_ascii=False)[:200]}...")
            
            try:
                response = requests.post(
                    self.base_url,
                    headers=self.headers,
                    json=data,
                    timeout=30
                )
                logger.debug(f"[AI评估-反馈版] 请求发送成功")
            except UnicodeEncodeError as e:
                logger.error(f"[AI评估-反馈版] 编码错误: {str(e)}")
                logger.error(f"[AI评估-反馈版] 错误位置: {e.start}:{e.end}")
                logger.error(f"[AI评估-反馈版] 错误字符串: {repr(data.get('messages', [{}])[0].get('content', '')[:100])}")
                raise
            except Exception as e:
                logger.error(f"[AI评估-反馈版] 发送请求时出错: {str(e)}")
                logger.error(f"[AI评估-反馈版] 错误类型: {type(e)}")
                raise
            
            logger.debug(f"[AI评估-反馈版] API响应状态码: {response.status_code}")
            if response.status_code == 200:
                result = response.json()
                content = result['choices'][0]['message']['content']
                
                # 清理响应内容
                clean_content = content.strip()
                if clean_content.startswith('```json'):
                    clean_content = clean_content[7:]
                if clean_content.endswith('```'):
                    clean_content = clean_content[:-3]
                clean_content = clean_content.strip()
                
                # 解析JSON
                logger.debug(f"[AI评估-反馈版] API返回内容: {clean_content[:200]}...")
                try:
                    evaluation_result = json.loads(clean_content)
                    logger.info(f"[AI评估-反馈版] 评估成功 - 分数: {evaluation_result.get('score', 0)}, 是否合理: {evaluation_result.get('is_reasonable', False)}")
                    
                    return {
                        'success': True,
                        'score': evaluation_result.get('score', 0),
                        'is_reasonable': evaluation_result.get('is_reasonable', False),
                        'reason': evaluation_result.get('reason', ''),
                        'strengths': evaluation_result.get('strengths', []),
                        'weaknesses': evaluation_result.get('weaknesses', []),
                        'user_feedback_adopted': evaluation_result.get('user_feedback_adopted', False),
                        'feedback_explanation': evaluation_result.get('feedback_explanation', ''),
                        'raw_response': content
                    }
                except json.JSONDecodeError as e:
                    logger.warning(f"[AI评估-反馈版] JSON解析失败: {str(e)}")
                    # 返回默认结果
                    return {
                        'success': False,
                        'error': 'JSON解析失败',
                        'score': 0,
                        'is_reasonable': False,
                        'reason': '评估失败',
                        'strengths': [],
                        'weaknesses': [],
                        'user_feedback_adopted': False,
                        'feedback_explanation': '解析失败'
                    }
                
        except requests.exceptions.Timeout:
            logger.error("[AI评估-反馈版] API请求超时")
        except Exception as e:
            logger.error(f"[AI评估-反馈版] 评估过程中发生错误: {str(e)}", exc_info=True)
        
        # 默认返回
        logger.warning("[AI评估-反馈版] 评估失败，返回默认结果")
        return {
            'success': False,
            'error': '评估失败',
            'score': 0,
            'is_reasonable': False,
            'reason': '评估失败',
            'strengths': [],
            'weaknesses': [],
            'user_feedback_adopted': False,
            'feedback_explanation': '评估失败'
        }
    
    def generate_improved_prompt(self, user_feedback: str, original_prompt: str) -> str:
        """
        根据用户反馈生成改进的提示词
        
        Args:
            user_feedback: 用户的反馈和建议
            original_prompt: 原始提示词
            
        Returns:
            改进后的提示词
        """
        print("\n" + "="*80)
        print("[AI提示词优化] ========== 开始优化提示词 ==========")
        print(f"[AI提示词优化] 📋 用户反馈长度: {len(user_feedback)}")
        print(f"[AI提示词优化] 📏 原始提示词长度: {len(original_prompt)}")
        print(f"[AI提示词优化] 💬 用户反馈预览: {user_feedback[:200]}...")
        logger.info("[AI提示词优化] 根据用户反馈生成改进的提示词")
        logger.info(f"[AI提示词优化] 用户反馈长度: {len(user_feedback)}")
        logger.info(f"[AI提示词优化] 原始提示词长度: {len(original_prompt)}")
        
        try:
            improvement_prompt = f"""你是一个专业的AI提示词优化专家。请根据用户的反馈和建议，改进以下评估提示词。

**用户的反馈和建议**：
{user_feedback}

**原始提示词**：
{original_prompt}

**优化要求**：
1. 保持提示词的核心评估框架不变
2. 根据用户反馈调整评估标准和权重
3. 增加用户提到的评估维度或关注点
4. 确保提示词更准确、更能捕获用户关心的评估要点
5. 保持提示词结构清晰，便于AI理解

请返回改进后的完整提示词（不要添加额外的说明文字，直接返回改进后的提示词内容）："""
            
            data = {
                "model": "deepseek-chat",
                "messages": [
                    {
                        "role": "user",
                        "content": improvement_prompt
                    }
                ],
                "temperature": 0.3,
                "max_tokens": 2000
            }
            
            print(f"[AI提示词优化] 🌐 发送请求到API: {self.base_url}")
            logger.debug(f"[AI提示词优化] 发送请求到API: {self.base_url}")
            
            response = requests.post(
                self.base_url,
                headers=self.headers,
                json=data,
                timeout=30
            )
            
            print(f"[AI提示词优化] 📥 API响应状态码: {response.status_code}")
            logger.debug(f"[AI提示词优化] API响应状态码: {response.status_code}")
            
            if response.status_code == 200:
                result = response.json()
                improved_prompt = result['choices'][0]['message']['content'].strip()
                
                print(f"[AI提示词优化] ✅ 成功生成改进的提示词，长度: {len(improved_prompt)}")
                print(f"[AI提示词优化] 📄 改进后的提示词预览: {improved_prompt[:300]}...")
                logger.info(f"[AI提示词优化] 成功生成改进的提示词，长度: {len(improved_prompt)}")
                logger.debug(f"[AI提示词优化] 改进后的提示词预览: {improved_prompt[:300]}...")
                print("="*80 + "\n")
                
                return improved_prompt
            else:
                print(f"[AI提示词优化] ❌ API返回错误: {response.status_code}")
                print(f"[AI提示词优化] 返回原始提示词")
                logger.error(f"[AI提示词优化] API返回错误: {response.status_code}")
                logger.warning("[AI提示词优化] 返回原始提示词")
                print("="*80 + "\n")
                return original_prompt
                
        except Exception as e:
            print(f"[AI提示词优化] ❌ 生成改进提示词失败: {str(e)}")
            print("[AI提示词优化] 返回原始提示词")
            logger.error(f"[AI提示词优化] 生成改进提示词失败: {str(e)}", exc_info=True)
            logger.warning("[AI提示词优化] 返回原始提示词")
            import traceback
            print(f"[AI提示词优化] 错误堆栈:\n{traceback.format_exc()}")
            print("="*80 + "\n")
            return original_prompt
    
    def evaluate_with_custom_prompt(self, user_message: str, ai_reply: str, custom_prompt: str) -> Dict:
        """
        使用自定义提示词评估AI回复是否合理
        
        Args:
            user_message: 用户消息
            ai_reply: AI回复
            custom_prompt: 自定义提示词（包含完整评估任务的提示词模板）
            
        Returns:
            评估结果字典
        """
        logger.info("[AI评估-自定义提示词] 开始使用自定义提示词评估回复合理性")
        logger.info(f"[AI评估-自定义提示词] 用户消息长度: {len(user_message)}")
        logger.info(f"[AI评估-自定义提示词] AI回复长度: {len(ai_reply)}")
        logger.info(f"[AI评估-自定义提示词] 自定义提示词长度: {len(custom_prompt)}")
        
        try:
            # 使用自定义提示词构建最终的prompt
            # custom_prompt应该包含模板，我们需要替换其中的用户消息和AI回复
            final_prompt = custom_prompt.replace('{user_message}', user_message).replace('{ai_reply}', ai_reply)
            
            # 如果替换后没有变化，说明custom_prompt是完整的提示词，直接使用
            if final_prompt == custom_prompt:
                # 手动构建提示词
                final_prompt = f"""{custom_prompt}

## 用户消息
{user_message}

## AI回复
{ai_reply}

## 输出要求
请按照以下JSON格式返回评估结果：
{{
    "score": 评分(0-100),
    "is_reasonable": true/false,
    "reason": "详细的评估理由",
    "strengths": ["具体的优点列表"],
    "weaknesses": ["具体的缺点列表"],
    "user_feedback_adopted": true,
    "feedback_explanation": "使用最新提示词进行评估"
}}
"""
            
            logger.debug(f"[AI评估-自定义提示词] 最终提示词长度: {len(final_prompt)}")
            logger.debug(f"[AI评估-自定义提示词] 提示词预览: {final_prompt[:300]}...")
            
            data = {
                "model": "deepseek-chat",
                "messages": [
                    {
                        "role": "user",
                        "content": final_prompt
                    }
                ],
                "temperature": 0.1,
                "max_tokens": 1500
            }
            
            # 发送请求
            logger.debug(f"[AI评估-自定义提示词] 发送请求到API: {self.base_url}")
            response = requests.post(
                self.base_url,
                headers=self.headers,
                json=data,
                timeout=30
            )
            
            logger.debug(f"[AI评估-自定义提示词] API响应状态码: {response.status_code}")
            if response.status_code == 200:
                result = response.json()
                content = result['choices'][0]['message']['content']
                
                # 清理响应内容
                clean_content = content.strip()
                if clean_content.startswith('```json'):
                    clean_content = clean_content[7:]
                if clean_content.endswith('```'):
                    clean_content = clean_content[:-3]
                clean_content = clean_content.strip()
                
                # 解析JSON
                logger.debug(f"[AI评估-自定义提示词] API返回内容: {clean_content[:200]}...")
                try:
                    evaluation_result = json.loads(clean_content)
                    logger.info(f"[AI评估-自定义提示词] 评估成功 - 分数: {evaluation_result.get('score', 0)}, 是否合理: {evaluation_result.get('is_reasonable', False)}")
                    
                    return {
                        'success': True,
                        'score': evaluation_result.get('score', 0),
                        'is_reasonable': evaluation_result.get('is_reasonable', False),
                        'reason': evaluation_result.get('reason', ''),
                        'strengths': evaluation_result.get('strengths', []),
                        'weaknesses': evaluation_result.get('weaknesses', []),
                        'user_feedback_adopted': True,
                        'feedback_explanation': '使用最新提示词进行评估',
                        'raw_response': content
                    }
                except json.JSONDecodeError as e:
                    logger.warning(f"[AI评估-自定义提示词] JSON解析失败: {str(e)}")
                    return {
                        'success': False,
                        'error': 'JSON解析失败',
                        'score': 0,
                        'is_reasonable': False,
                        'reason': '评估失败',
                        'strengths': [],
                        'weaknesses': [],
                        'user_feedback_adopted': False,
                        'feedback_explanation': '解析失败'
                    }
            else:
                logger.error(f"[AI评估-自定义提示词] API返回错误: {response.status_code}")
                
        except requests.exceptions.Timeout:
            logger.error("[AI评估-自定义提示词] API请求超时")
        except Exception as e:
            logger.error(f"[AI评估-自定义提示词] 评估过程中发生错误: {str(e)}", exc_info=True)
        
        # 默认返回
        logger.warning("[AI评估-自定义提示词] 评估失败，返回默认结果")
        return {
            'success': False,
            'error': '评估失败',
            'score': 0,
            'is_reasonable': False,
            'reason': '评估失败',
            'strengths': [],
            'weaknesses': [],
            'user_feedback_adopted': False,
            'feedback_explanation': '评估失败'
        }
    
    def filter_first_message(self, messages: List[Dict]) -> List[Dict]:
        """
        过滤主动候选人的第一条消息
        
        Args:
            messages: 消息列表
            
        Returns:
            过滤后的消息列表
        """
        if not messages:
            return messages
        
        # 检查第一条消息是否是AI发送的
        first_message = messages[0]
        if first_message.get('sender') == '我':
            # 检查是否是主动候选人的第一条消息
            first_message_content = first_message.get('content', '')
            
            # 检查是否包含主动候选人的特征内容
            active_candidate_patterns = [
                '您好吖',
                '我们提供日结',
                '133元-299元',
                '首月收入6000-8000元',
                '第二月8000-20000元',
                '四个小时/天',
                '接受无经验',
                '无需面试',
                '每天下播后',
                '微信结算',
                '无礼物收入也发同样',
                '保底到账',
                '收到回复1'
            ]
            
            # 如果包含这些特征，则过滤掉第一条消息
            if any(pattern in first_message_content for pattern in active_candidate_patterns):
                logger.info("检测到主动候选人第一条消息，已过滤")
                return messages[1:]  # 返回除第一条消息外的所有消息
        
        return messages


class SalaryAnalyzer:
    """薪资信息分析器"""
    
    def __init__(self, evaluator: DeepSeekEvaluator):
        """
        初始化分析器
        
        Args:
            evaluator: DeepSeek评估器实例
        """
        self.evaluator = evaluator
    
    def analyze_candidate_messages(self, candidate_id: int, messages: List[Dict]) -> Dict:
        """
        分析候选人的所有消息
        
        Args:
            candidate_id: 候选人ID
            messages: 消息列表
            
        Returns:
            分析结果
        """
        # 过滤主动候选人第一条消息
        filtered_messages = self.evaluator.filter_first_message(messages)
        
        if not filtered_messages:
            return {
                'candidate_id': candidate_id,
                'total_messages': len(messages),
                'filtered_messages': 0,
                'salary_related_messages': [],
                'non_salary_related_messages': [],
                'salary_count': 0,
                'non_salary_count': 0,
                'salary_rate': 0.0
            }
        
        # 批量评估消息
        evaluation_results = self.evaluator.batch_evaluate_messages(filtered_messages)
        
        # 分类消息
        salary_related_messages = []
        non_salary_related_messages = []
        
        for i, result in enumerate(evaluation_results):
            if i < len(filtered_messages):
                message = filtered_messages[i]
                message_with_evaluation = {
                    'id': message.get('id', i),
                    'content': message.get('content', ''),
                    'sender': message.get('sender', ''),
                    'created_at': message.get('created_at', ''),
                    'evaluation': result
                }
                
                if result.get('is_salary_related', False):
                    salary_related_messages.append(message_with_evaluation)
                else:
                    non_salary_related_messages.append(message_with_evaluation)
        
        # 计算统计信息
        total_filtered = len(filtered_messages)
        salary_count = len(salary_related_messages)
        non_salary_count = len(non_salary_related_messages)
        salary_rate = (salary_count / total_filtered * 100) if total_filtered > 0 else 0.0
        
        return {
            'candidate_id': candidate_id,
            'total_messages': len(messages),
            'filtered_messages': total_filtered,
            'salary_related_messages': salary_related_messages,
            'non_salary_related_messages': non_salary_related_messages,
            'salary_count': salary_count,
            'non_salary_count': non_salary_count,
            'salary_rate': round(salary_rate, 2)
        }
    
    def analyze_all_candidates(self, candidates_data: List[Dict], test_mode: bool = False, test_limit: int = None) -> Dict:
        """
        分析所有候选人的消息
        
        Args:
            candidates_data: 候选人数据列表
            test_mode: 测试模式，只处理限制数量的消息
            test_limit: 测试模式下的限制数量
            
        Returns:
            总体分析结果
        """
        all_salary_messages = []
        all_non_salary_messages = []
        candidate_analyses = []
        
        total_candidates = len(candidates_data)
        total_messages = 0
        total_salary_messages = 0
        
        processed_count = 0
        for candidate in candidates_data:
            candidate_id = candidate.get('id')
            messages = candidate.get('chat_history', [])
            
            # 测试模式：只处理前5条AI消息
            if test_mode and test_limit:
                ai_messages = [msg for msg in messages if msg.get('sender') == '我']
                if len(ai_messages) > test_limit:
                    print(f"[测试模式] 候选人 {candidate_id} 有 {len(ai_messages)} 条AI消息，限制为 {test_limit} 条")
                    # 只保留前test_limit条AI消息
                    limited_ai = ai_messages[:test_limit]
                    # 重组消息列表，保留所有消息但只评估前test_limit条
                    # 这里简化处理：只处理包含前test_limit条AI消息的消息
                    ai_indices = [i for i, msg in enumerate(messages) if msg.get('sender') == '我']
                    if len(ai_indices) > test_limit:
                        messages = messages[:ai_indices[test_limit-1]+1] if len(ai_indices) > test_limit else messages
            
            # 分析单个候选人
            analysis = self.analyze_candidate_messages(candidate_id, messages)
            candidate_analyses.append(analysis)
            processed_count += 1
            
            # 测试模式：只处理前5个候选人
            if test_mode and test_limit and processed_count >= test_limit:
                print(f"[测试模式] 已处理 {processed_count} 个候选人，停止处理")
                break
            
            # 收集所有消息
            all_salary_messages.extend(analysis['salary_related_messages'])
            all_non_salary_messages.extend(analysis['non_salary_related_messages'])
            
            total_messages += analysis['total_messages']
            total_salary_messages += analysis['salary_count']
        
        # 计算总体统计
        overall_salary_rate = (total_salary_messages / total_messages * 100) if total_messages > 0 else 0.0
        
        return {
            'total_candidates': total_candidates,
            'total_messages': total_messages,
            'total_salary_messages': total_salary_messages,
            'total_non_salary_messages': len(all_non_salary_messages),
            'overall_salary_rate': round(overall_salary_rate, 2),
            'candidate_analyses': candidate_analyses,
            'all_salary_messages': all_salary_messages,
            'all_non_salary_messages': all_non_salary_messages
        }


def create_evaluator(api_key: str) -> DeepSeekEvaluator:
    """
    创建DeepSeek评估器实例
    
    Args:
        api_key: DeepSeek API密钥
        
    Returns:
        DeepSeekEvaluator实例
    """
    return DeepSeekEvaluator(api_key)


def create_analyzer(api_key: str) -> SalaryAnalyzer:
    """
    创建薪资分析器实例
    
    Args:
        api_key: DeepSeek API密钥
        
    Returns:
        SalaryAnalyzer实例
    """
    evaluator = create_evaluator(api_key)
    return SalaryAnalyzer(evaluator)


if __name__ == "__main__":
    # 测试代码
    api_key = "sk-c4c1f1dee680477ea17a5315431d9a4d"
    
    # 创建评估器
    evaluator = create_evaluator(api_key)
    
    # 测试单条消息评估
    test_message = "您好吖，我们提供日结133元-299元工作岗位【首月收入6000-8000元，第二月8000-20000元】四个小时/天，接受无经验，无需面试，每天下播后→微信结算（无礼物收入也发同样133-299元/天，保底到账哈），收到回复1"
    
    print("测试单条消息评估...")
    result = evaluator.evaluate_salary_info(test_message)
    print(f"评估结果: {json.dumps(result, ensure_ascii=False, indent=2)}")
    
    # 测试消息过滤
    test_messages = [
        {
            'id': 1,
            'content': test_message,
            'sender': '我',
            'created_at': '2024-01-01 10:00:00'
        },
        {
            'id': 2,
            'content': '好的，我想了解一下具体的工作内容',
            'sender': '候选人',
            'created_at': '2024-01-01 10:01:00'
        }
    ]
    
    print("\n测试消息过滤...")
    filtered = evaluator.filter_first_message(test_messages)
    print(f"过滤后消息数量: {len(filtered)}")
    for msg in filtered:
        print(f"- {msg['sender']}: {msg['content'][:50]}...")
